#include "taskQueue.h"

void task_queue_init(task_queue_t *queue) {
    queue->head = queue->tail = NULL;
    queue->size = 0;
    pthread_mutex_init(&queue->mutex, NULL);
    pthread_cond_init(&queue->cond, NULL);
}

void task_queue_push(task_queue_t *queue, task_t *task) {
    task->next = NULL;

    pthread_mutex_lock(&queue->mutex);

    if (queue->tail) {
        queue->tail->next = task;
    } else {
        queue->head = task;
    }
    queue->tail = task;
    queue->size++;

    pthread_cond_signal(&queue->cond);
    pthread_mutex_unlock(&queue->mutex);
}

task_t *task_queue_pop(task_queue_t *queue) {
    pthread_mutex_lock(&queue->mutex);

    while (queue->size == 0) {
        pthread_cond_wait(&queue->cond, &queue->mutex);
    }

    task_t *task = queue->head;
    queue->head = task->next;
    if (!queue->head) queue->tail = NULL;
    queue->size--;

    pthread_mutex_unlock(&queue->mutex);
    return task;
}

void task_queue_destroy(task_queue_t *queue) {
    pthread_mutex_destroy(&queue->mutex);
    pthread_cond_destroy(&queue->cond);
}

